#pragma once

#include "ErrorContainer.h"
#include "Tree.h"

using namespace std;

struct curState
{
	string lastStackVar;
	string currentType;
	int unic_postfix;
	bool isAssignment;
};

struct varInfo
{
	string variableName;
	string variableType;
	bool notMassiv;

};

class CodeGenerator
{
public:
	CodeGenerator(Tree syntaxTree);
	~CodeGenerator(void);
	void run(string fileName);
private:
	void GenerateOutputCode();
	void CreateDefineCode(string fileWithDefineCode);
	void AddDefineCodePiece();
    vector<string> AddVectors();
	string GetCode(string type, vector<string> valueArr, curState * state, int * label);
	string GenerateDeclar(string type, string var);
	string GenerateAssignment(string var1, string var2, curState * state);
	string GeneratePostExpAssignment(string var1, string var2, curState * state);
	string GenerateArithmetic(string var1, string var2, string key, curState * state);
	string GenerateIf(string var1, string var2, string var3, curState * state, int * label);
	string GenerateElse(string var1, int * label);
	string GenerateWrite(string var1, string var2, curState * state);
	string GenerateCMPRelEqu(string var1, string var2, string key, curState * state);
	string GenerateLogic(string var1, string var2, string key, curState * state);
	string GenerateDeclarMassiv(string var1, string var2, curState * state);
	string GenerateWhile(string var1, string var2, curState * state, int * label);
	string GenerateDoWhile(string var1, string var2, curState * state, int * label);
	string GenerateFor(string var1, string var2, string var3, curState * state, int * label);
	string GenerateMassiv(string var, curState * state);
    string GenerateMassiv_assignment(string var, curState * state);
	string GenerateStrCmp(string var1, string var2, string var3, string var4, curState * state);
	string GenerateStrLen(string var1, string var2, curState * state);
	string GenerateFindSubStr(string var1, string var2, string var3, curState * state);
	Tree m_synTree;
	vector<string>  m_varStack;
	vector<string>  m_define;
	vector<string>  m_outputProgramCode;
	vector<varInfo> m_variables;
	vector<vector<string>>  m_array;
};
